#ifndef __M_FACTORY_H__
#define __M_FACTORY_H__
#include "connection.hpp"
#include "worker.hpp"
namespace zhong
{
    class ConsumerClient
    {
    public:
        using ptr = std::shared_ptr<ConsumerClient>;
        ConsumerClient(const Channel::ptr &channel) : _channel(channel) {}
        // // 选择虚拟机
        bool selectVirtualHost(const std::string &host_name)
        {
            return _channel->selectVirtualHost(host_name);
        }
        // 声明队列
        bool declareQueue(const std::string &queue_name,
                          bool durable,
                          bool exclusive,
                          bool auto_delete,
                          const google::protobuf::Map<std::string, std::string> &args_map)
        {
            return _channel->declareQueue(queue_name, durable, exclusive, auto_delete, args_map);
        }
        // 删除队列
        void deleteQueue(const std::string &queue_name)
        {
            return _channel->deleteQueue(queue_name);
        }
        // 绑定队列
        bool bind(const std::string &exchange_name, const std::string &queue_name, const std::string &binding_key)
        {
            return _channel->bind(exchange_name, queue_name, binding_key);
        }
        // 取消队列绑定
        void unBind(const std::string &exchange_name, const std::string &queue_name)
        {
            return _channel->unBind(exchange_name, queue_name);
        }
        // 订阅队列信息
        bool basicConsume(const std::string &consumer_tag, const std::string &queue_name, bool auto_ack)
        {
            ConsumerCallback func = std::bind(&ConsumerClient::callback, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3);
            return _channel->basicConsume(consumer_tag, queue_name, auto_ack, func);
        }
        // 手动进行消息确认
        void basicAck(const std::string &message_id)
        {
            return _channel->basicAck(message_id);
        }
        // 取消订阅
        void basicCancel()
        {
            return _channel->basicCancel();
        }

    private:
        void callback(const std::string &consumer_tag, const zhong::BasicProperties *bp, const std::string &body)
        {
            DEBUG_LOG("消费者[%s]接收到消息[%s]", consumer_tag.c_str(), body.c_str());
            _channel->basicAck(bp->id()); // 是否需要增加自动确认标志

            // 接下来就是针对这个回调函数进行处理了
        }

    private:
        Channel::ptr _channel;
    };

    class ProducerClient
    {
    public:
        using ptr = std::shared_ptr<ProducerClient>;
        ProducerClient(const Channel::ptr &channel) : _channel(channel) {}
        // 选择虚拟机
        bool selectVirtualHost(const std::string &host_name)
        {
            return _channel->selectVirtualHost(host_name);
        }
        // 声明交换机
        bool declareExchange(const std::string &exchange_name,
                             ExchangeType type,
                             bool durable,
                             bool auto_delete,
                             const google::protobuf::Map<std::string, std::string> &args_map)
        {
            return _channel->declareExchange(exchange_name, type, durable, auto_delete, args_map);
        }
        // 删除交换机
        void deleteExchange(const std::string &exchange_name)
        {
            return _channel->deleteExchange(exchange_name);
        }
        // 消息发布
        bool basicPublish(const std::string &exchange_name, const BasicProperties *bp, const std::string &body)
        {
            return _channel->basicPublish(exchange_name, bp, body);
        }


    private:
        Channel::ptr _channel;
    };

    class ManagerCilent
    {
    public:
        using ptr = std::shared_ptr<ManagerCilent>;
        ManagerCilent(const Channel::ptr &channel) : _channel(channel) {}
        bool declareVirtualHost(const std::string &host_name, bool durable)
        {
            return _channel->declareVirtualHost(host_name, durable);
        }
        void deleteVirtualHost(const std::string &host_name)
        {
            return _channel->deleteVirtualHost(host_name);
        }

    private:
        Channel::ptr _channel;
    };
    // 外部通过FactoryCilent 来创建
    class FactoryCilent
    {
    public:
        static ConsumerClient::ptr createConsumerClient(const Channel::ptr &channel)
        {
            return std::make_shared<ConsumerClient>(channel);
        }
        static ProducerClient::ptr createProducerClient(const Channel::ptr &channel)
        {
            return std::make_shared<ProducerClient>(channel);
        }
        static ManagerCilent::ptr createManagerCilent(const Channel::ptr &channel)
        {
            return std::make_shared<ManagerCilent>(channel);
        }
    };
};

#endif